package ru.ipo.dces.plugins.admin.components;


import info.clearthought.layout.TableLayout;
import ru.ipo.dces.client.ContestConnection;
import ru.ipo.dces.client.Controller;
import ru.ipo.dces.client.components.StatusBar;
import ru.ipo.dces.client.messages.PopupMessageType;
import ru.ipo.dces.clientservercommunication.ContestDescription;
import ru.ipo.dces.exceptions.GeneralRequestFailureException;
import ru.ipo.dces.exceptions.ServerReturnedError;
import ru.ipo.dces.plugins.admin.*;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.util.Date;

import static java.awt.event.KeyEvent.*;

public class LoginPluginMainLoginPanel extends JPanel {
    private ContestDescription contestDescription;
    private JTextField loginEdit;
    private JPasswordField passwordEdit;
    private JButton loginButton;

    public LoginPluginMainLoginPanel() {
        int separatorGap = 5;
        setLayout(new TableLayout(new double[]{separatorGap, TableLayout.FILL, TableLayout.PREFERRED,
                separatorGap},
                new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, separatorGap, TableLayout.PREFERRED,
                        TableLayout.PREFERRED, separatorGap, TableLayout.PREFERRED}));
        loginButton = new JButton("Войти");

        add(loginButton, "2, 6");

        add(new JLabel("Логин"), "1, 0");
        add(new JLabel("Пароль"), "1, 3");

        loginEdit = new JTextField();
        passwordEdit = new JPasswordField();
        add(loginEdit, "1, 1, 2, 1");
        add(passwordEdit, "1, 4, 2, 4");
        loginButton.setEnabled(false);
        addListeners();
    }

    public void resetPanel() {
        loginEdit.setText("");
        passwordEdit.setText("");
        contestDescription = null;
        loginButton.setEnabled(false);
    }

    private void addListeners() {
        ActionListener inputListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                if (contestDescription == null) return;
                login(loginEdit.getText(), passwordEdit.getPassword(), contestDescription);
            }
        };
        loginButton.addActionListener(inputListener);
        loginEdit.registerKeyboardAction(inputListener, KeyStroke.getKeyStroke(VK_ENTER, 0, false), WHEN_FOCUSED);
        passwordEdit.registerKeyboardAction(inputListener, KeyStroke.getKeyStroke(VK_ENTER, 0, false), WHEN_FOCUSED);
    }

    public void login(String login, char[] password, ContestDescription contest) {
        StatusBar.Message enteringMessage = Controller.getClientDialog().getStatusBar().addMessage("Выполняется вход");

        try {
            Controller.connectToContest(contest, login, password);

            //show message like: 'ok, connected, finish is at...'
            String leftTimeMessage;
            ContestConnection con = Controller.getContestConnection();
            switch (con.getUser().userType) {
                case SuperAdmin:
                    leftTimeMessage = "Суперадминистратор";
                    break;
                case ContestAdmin:
                    leftTimeMessage = "Администратор соревнования";
                    break;
                case Participant:
                    Date now = new Date();
                    if (now.before(con.getFinishTime()))
                        //TODO format only time if the finish is today
                        leftTimeMessage = "Окончание соревнования в " + DateFormat.getInstance().format(con.getFinishTime());
                    else
                        leftTimeMessage = "Соревнование уже закончилось";
                    break;
                default:
                    leftTimeMessage = "?? Неизвестный тип пользователя";
            }

            Controller.showPopupMessage("Успешное подключение к соревнованию " + leftTimeMessage, PopupMessageType.Info);

            // Удаляем все запущенные Plugin'ы
            Controller.getClientDialog().clearLeftPanel();

            // Если пользователь администратор или администратор сервера
            // загружаем ему административные Plugin'ы
            switch (con.getUser().userType) {
                case ContestAdmin:
                    Controller.addAdminPlugin(ContestPluginV3.class);
                    Controller.addAdminPlugin(ManageUsersPluginV2.class);
                    Controller.addAdminPlugin(ResultsPlugin.class);
                    Controller.addAdminPlugin(LogoutPluginV2.class);
                    break;
                case SuperAdmin:
                    Controller.addAdminPlugin(ContestPluginV3.class);
                    Controller.addAdminPlugin(ManageUsersPluginV2.class);
                    Controller.addAdminPlugin(PluginsManagementPluginV2.class);
                    Controller.addAdminPlugin(ResultsPlugin.class);
                    Controller.addAdminPlugin(LogoutPluginV2.class);
                    Controller.addAdminPlugin(TestServletsPlugin.class);
                    break;
                case Participant:
                    // Получаем данные о задачах
                    Controller.refreshParticipantInfo(false, false);
            }

        } catch (GeneralRequestFailureException e) {
            Controller.showPopupMessage(e.getMessage(), PopupMessageType.GeneralServerError);
        } catch (ServerReturnedError serverReturnedError) {
            Controller.showPopupMessage(serverReturnedError.getMessage(), PopupMessageType.ServerReturnedError);
        } finally {
            Controller.getClientDialog().getStatusBar().removeMessage(enteringMessage);
        }
    }

    public void setContest(ContestDescription contest) {
        contestDescription = contest;
        loginButton.setEnabled(!(contestDescription == null));
    }
}
